package com.basic.business.rpaServer;

import com.basic.business.common.constants.Constants;
import com.basic.business.common.enums.PstStatus;
import com.basic.business.common.redis.RedisCacheUtils;
import com.basic.business.common.utils.FileUtils;
import com.basic.business.common.utils.StringUtils;
import com.basic.business.common.utils.UserUtils;
import com.basic.business.common.utils.kmUtil.KmTagsUtils;
import com.basic.business.log.service.ITOrdersLogService;
import com.basic.business.memoType.MemoTypeUtils;
import com.basic.business.order.domain.TOrdersMain;
import com.basic.business.order.domain.TOrdersMerge;
import com.basic.business.order.domain.TOrdersStatus;
import com.basic.business.order.service.ITOrdersMainService;
import com.basic.business.order.service.ITOrdersStatusService;
import com.basic.business.order.service.ITOrdersTimeLineService;
import com.basic.business.redis.domain.TOrdersMainRedis;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Component
public class HandleWaitAudit {

    @Resource
    private ITOrdersMainService mainService;

    @Resource
    private ITOrdersStatusService statusService;

    @Resource
    private ITOrdersLogService logService;

    @Resource
    private ITOrdersTimeLineService timeLineService;

    @Resource
    private HandlePackaging packaging;


    public void init(TOrdersMain main){

        // 合单明细状态中包含CLOSED（交易关闭）、CANCEL（交易取消）
        handleClosedOrCancel(main);

        // 订单明细备注中包含【人工处理】的，更新Redis中的自动处理状态为【人工处理】，删除打包文件，删除不做处理的标签，新增正常处理标签
        boolean isManualProcess = handleManualProcess(main);
        if (isManualProcess) return;

        // 文件打包
        packaging.init(main);

    }

    /**
     * 人工处理订单操作
     */
    private boolean handleManualProcess(TOrdersMain main){
        // 获取主订单SID
        long mainSid = main.getSid();

        TOrdersStatus status = TOrdersStatus.createTOrdersStatus(main);
        // 更新主订单自动处理状态为【人工处理】
        status.setOrderStatus(PstStatus.MANUAL.name());

        try {
            // 订单备注是否包含【人工处理】
            boolean isDetailsContains = main.getMergeList().stream().anyMatch(detail -> StringUtils.contains(detail.getSellerMemo(), "【人工处理】"));
            if (isDetailsContains) {
                TOrdersMainRedis mainRedis = RedisCacheUtils.getCacheObject(Constants.ORDERS_REDIS_KEY + mainSid);
                // 删除打包文件
                mainRedis.getDetailList().forEach(detail -> {
                    // 获取smb路径
                    String smbPath = detail.getSmbPath();
                    if (StringUtils.isNotNull(smbPath)) {
                        // 删除打包文件 按逗号分割路径并逐个删除
                        Arrays.stream(smbPath.split(","))
                                .filter(path -> StringUtils.isNotBlank(path.trim()))
                                .forEach(path -> FileUtils.deleteFromSmb(path, main.getShortId()));
                        // 将SMB路径清空
                        detail.setSmbPath(null);
                    }
                });

                // 如果明细中存在非【人工处理】的标签 则更新标签，记录日志
                if (mainRedis.getDetailList().stream().anyMatch(detail -> !StringUtils.contains(detail.getPst(), "MANUAL"))) {

                    // 设置自动处理状态为人工
                    mainRedis.getDetailList().forEach(detail -> detail.setPst(PstStatus.MANUAL.name()));
                    RedisCacheUtils.setCacheObject(Constants.ORDERS_REDIS_KEY + mainSid, mainRedis);

                    statusService.insertPst(status);

                    // 更新标签 新增正常处理标签，删除不做处理标签，删除印刷品标签
                    String tagsStr = KmTagsUtils.updateExclusiveTag(mainSid, main.getTags(), KmTagsUtils.TAG_NORMAL_PROCESSING);
                    if (StringUtils.isNotBlank(tagsStr)) {
                        // 写日志
                        logService.insert(mainSid, mainSid, String.format("执行【人工处理】策略成功；%s", tagsStr));
                    }
                }
                return true;
            }
        } catch (Exception e) {
            // 更新主订单自动处理状态为【人工处理】
            status.setOrderStatus(PstStatus.MANUAL.name());
            statusService.insertPst(status);
            // 更新标签 新增正常处理标签，删除不做处理标签，删除印刷品标签
            String tagsStr = KmTagsUtils.updateExclusiveTag(mainSid, main.getTags(), KmTagsUtils.TAG_NORMAL_PROCESSING);
            // 写日志
            logService.insert(mainSid, mainSid, String.format("执行【人工处理】策略失败；%s", tagsStr));
            log.error("执行【人工处理】策略失败；系统单号：{}；原因：", mainSid, e);
            return false;
        }
        return false;
    }

    /**
     * 合单明细中isMergeMain是0且状态中包含CLOSED（交易关闭）、CANCEL（交易取消）
     */
    private void handleClosedOrCancel(TOrdersMain main){
        // 合单明细中isMergeMain是0且状态中包含CLOSED（交易关闭）、CANCEL（交易取消）的集合
        List<TOrdersMerge> merges = main.getMergeList().stream().filter(merge -> merge.getIsMergeMain() == 0 && StringUtils.containsAny(merge.getSysStatus(), "CLOSED", "CANCEL")).collect(Collectors.toList());

        merges.forEach(merge -> {
            // 从Redis中查找是否存在此订单
            TOrdersMainRedis mainRedis = RedisCacheUtils.getCacheObject(Constants.ORDERS_REDIS_KEY + merge.getMergeSid());
            if (Objects.nonNull(mainRedis)) {
                // 存在 说明是原来主订单退款的，删除Redis中的原信息且删除原来做包的文件
                deleteRedisAndFile(main, merge.getMergeSid());
            } else {
                // 不存在 说明是子订单退款，更新Redis中自动处理状态为成功和删包，并删除对应的做包文件
                updateRedisAndFile(main, merge.getMergeSid());
            }
        });
    }

    /**
     * 主订单退款，删除Redis中的订单和打包文件，删除掉数据库中订单信息
     */
    private void deleteRedisAndFile(TOrdersMain main, long mergeSid) {
        try {
            // 获取Redis中的信息
            TOrdersMainRedis mainRedis = RedisCacheUtils.getCacheObject(Constants.ORDERS_REDIS_KEY + mergeSid);
            // 删除打包文件
            mainRedis.getDetailList().forEach(detail -> {
                // 获取smb路径
                String smbPath = detail.getSmbPath();
                if (StringUtils.isNotBlank(smbPath)) {
                    // 删除打包文件 按逗号分割路径并逐个删除
                    Arrays.stream(smbPath.split(","))
                            .filter(path -> StringUtils.isNotBlank(path.trim()))
                            .forEach(path -> FileUtils.deleteFromSmb(path, main.getShortId()));
                }
            });

            // 删除Redis中的订单
            RedisCacheUtils.deleteObject(Constants.ORDERS_REDIS_KEY + mergeSid);

            // 删除数据库中对应的数据
            mainService.deleteByMainSid(mergeSid);
            // 更新日志
            logService.updateMainSid(mergeSid, main.getSid());

            // 更新状态
            statusService.updateMainSid(mergeSid, main.getSid(), main.getTid(), main.getShortId());

            // 更新时间线
            timeLineService.updateMainSid(mergeSid, main.getSid(), main.getTid(), main.getShortId());

        } catch (Exception e) {
            log.error("执行【合单主订单退款】策略失败；系统单号：{}，原因：", mergeSid, e);
        }
    }

    /**
     * 子订单退款，更新Redis中的订单和删除打包文件
     */
    private void updateRedisAndFile(TOrdersMain main, long mergeSid) {
        long mainSid = main.getSid();

        TOrdersStatus status = TOrdersStatus.createTOrdersStatus(main);

        try {
            TOrdersMainRedis mainRedis = RedisCacheUtils.getCacheObject(Constants.ORDERS_REDIS_KEY + mainSid);

            mainRedis.getDetailList().forEach(detail -> {
                // 子订单sid和mergeSid相同，删除打包文件，更新子订单自动处理状态为删包
                if (detail.getDetailSid() == mergeSid) {
                    // 设置自动处理状态为【删包】
                    detail.setPst(PstStatus.DELETED.name());
                    // 获取smb路径
                    String smbPath = detail.getSmbPath();

                    if (StringUtils.isNotBlank(smbPath)) {
                        // 删除打包文件 按逗号分割路径并逐个删除
                        Arrays.stream(smbPath.split(","))
                                .filter(path -> StringUtils.isNotBlank(path.trim()))
                                .forEach(path -> FileUtils.deleteFromSmb(path, main.getShortId()));
                    }

                    // 写日志
                    logService.insert(mainSid, mergeSid, String.format("执行【合单子订单退款】策略成功：%s", detail.getSmbPath()));
                    // 将SMB路径清空
                    detail.setSmbPath(null);
                }
            });
            RedisCacheUtils.setCacheObject(Constants.ORDERS_REDIS_KEY + mainSid, mainRedis);
        } catch (Exception e) {
            // 更新主订单自动处理状态为【人工处理】
            status.setOrderStatus(PstStatus.MANUAL.name());
            statusService.insertPst(status);
            // 写日志
            logService.insert(mainSid, mergeSid, "执行【合单子订单退款】策略失败；");
            log.error("执行【合单子订单退款】策略失败；系统单号：{}，原因：", mainSid, e);
        }
    }



}
